package com.lu.dog.dbrowser.ui;

import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.DownloadManager;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.support.v7.graphics.Palette;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.DownloadListener;
import android.webkit.SslErrorHandler;
import android.webkit.URLUtil;
import android.webkit.ValueCallback;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.lu.adog.base.BaseActivity;
import com.lu.adog.base.BaseConfig;
import com.lu.adog.util.Logg;
import com.lu.dog.dbrowser.R;
import com.lu.dog.dbrowser.bean.LogInfo;
import com.lu.dog.dbrowser.bean.SearchInfo;
import com.lu.dog.dbrowser.db.DBrowserDbHelper;
import com.lu.dog.dbrowser.ui.webview.ComponentJs;
import com.lu.dog.dbrowser.ui.webview.CustomWebViewClient;
import com.lu.dog.util.SearchTextUtil;
import com.lu.dog.util.StatusBarUtils;

import java.io.File;

/**
 * @author Yue
 * @date 2017/12/25 16:49
 */

public class WebActivity extends BaseActivity {
    private WebView webView;
    private ViewGroup contentView;
    private int statusBarHeight;

    private DownloadReceiver downloadReceiver;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web);

        assignViews();

        downloadReceiver = new DownloadReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
        registerReceiver(downloadReceiver, intentFilter);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            hideLoading();
        }
        return super.onTouchEvent(event);
    }

    private void assignViews() {

        contentView = (ViewGroup) findViewById(R.id.layoutWeb);

        webView = findViewById(R.id.webView);

//开启webview浏览器调试模式
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            webView.setWebContentsDebuggingEnabled(true);
        }

        WebSettings webSettings = webView.getSettings();

        webSettings.setJavaScriptEnabled(true);


//让WebView支持播放插件
        webSettings.setPluginState(WebSettings.PluginState.ON);

//设置脚本是否允许自动打开弹窗
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);

// 没有缓存，每次都加载。为了方便测试页面加载速度。
        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);

// 允许webview混合使用https和http
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            //默认api>=21后不允许从https加载http的资源
            webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }


        webSettings.setDomStorageEnabled(true);

//        默认启用了
//        webSettings.setAllowFileAccess(true);

        String url = getIntent().getStringExtra(BaseConfig.KEY_URL);

        url = SearchTextUtil.getFinalSearchText(url);
        if (url == null) {
            return;
        }

        Logg.d(">>>url:", url);
        webView.loadUrl(url);
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                try {
//                    String[] st=["http://", "https://", "ftp://", "file:///"];
//                    String[] ss = ["a","b"];
//                    baidumap://
                    if (!url.matches("^(http|ftp|https)://.*")) {
//                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
//                        startActivity(intent);
//                        view.loadUrl(url);
                        Logg.d(">>>", url);
                        return true;
                    }
                } catch (Exception e) {
                    Logg.w(">>>百度地图：", e);
                    return false;
                }
                return false;
            }

            @Override
            public void onPageCommitVisible(WebView view, String url) {
                showLoading();
                super.onPageCommitVisible(view, url);
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                long time = System.currentTimeMillis();
                Logg.w("访问", url + "");
                DBrowserDbHelper.getInstance(WebActivity.this).updateSearchInfo(new SearchInfo(url, null, time, time));

            }

            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                super.onReceivedError(view, request, error);
                String eText = null;
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                    eText = "ErrorCode:" + error.getErrorCode() + "\n\nDescription:\n" + error.getDescription();
                }
                String summary = eText;
                if (!TextUtils.isEmpty(summary)) {
                    summary = eText.substring(0, 40);
                }

//               缓存异常和错误，提供查看的方法
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    DBrowserDbHelper.getInstance(WebActivity.this).updateLogInfo(new LogInfo(0, request.getUrl().toString(), summary, eText, System.currentTimeMillis(), 0));
                } else {
                    DBrowserDbHelper.getInstance(WebActivity.this).updateLogInfo(new LogInfo(0, view.getUrl(), summary, eText, System.currentTimeMillis(), 0));
                }

            }

            @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                handler.proceed();//继续使用证书，忽略错误
                super.onReceivedSslError(view, handler, error);
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                hideLoading();
                super.onPageFinished(view, url);
                paletteStatusBar();

            }


        });

        webView.setWebChromeClient(new CustomWebViewClient(new ComponentJs()) {
            // For Android < 3.0
            public void openFileChooser(ValueCallback<Uri> valueCallback) {
                uploadMessage = valueCallback;
                openImageChooserActivity();
            }

            // For Android  >= 3.0
            public void openFileChooser(ValueCallback valueCallback, String acceptType) {
                uploadMessage = valueCallback;
                openImageChooserActivity();
            }

            //For Android  >= 4.1
            public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
                uploadMessage = valueCallback;
                openImageChooserActivity();
            }

            // For Android >= 5.0
            @Override
            public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
                uploadMessageAboveL = filePathCallback;
                openImageChooserActivity();
                return true;
            }
        });

//        webView.addJavascriptInterface(new ComponentJs(),JSName);

        webView.setDownloadListener(new ResDownloadListener());
    }

    AlertDialog selectDialog;

    private void switchSelectDialog() {
        if (selectDialog != null) {
            if (selectDialog.isShowing()) {
                selectDialog.dismiss();
            } else {
                selectDialog.show();
            }

        } else {
            selectDialog = new AlertDialog.Builder(this)
                    .setTitle("设置")
                    .setItems(new String[]{"适应屏幕", "原始尺寸"}, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            WebSettings setting = webView.getSettings();
                            if (which == 0) {
                                setting.setUseWideViewPort(true);
                                setting.setLoadWithOverviewMode(true);
                            } else {
                                setting.setUseWideViewPort(false);
                                setting.setLoadWithOverviewMode(false);
                            }
                            webView.reload();
                        }
                    }).show();
        }
    }

    private void hideSelectDialog() {
        if (selectDialog != null && selectDialog.isShowing()) {
            selectDialog.dismiss();
        }
    }

    private AlertDialog progressDialog;

    private void showLoading() {
        if (progressDialog == null) {

            progressDialog = new ProgressDialog.Builder(this)
                    .setView(new ProgressBar(WebActivity.this))
                    .show();
        }
    }

    private void hideLoading() {
        if (progressDialog != null && progressDialog.isShowing()) {
            progressDialog.cancel();
        }
    }

    //状态栏变色处理
    private void paletteStatusBar() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            return;
        }
//        // View是你需要截图的View
        View view = getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap bitmap = view.getDrawingCache();

//        Logg.w(">>>", bitmap.getHeight() + "=====");

        if (statusBarHeight != 0) {
            // 获取状态栏高度
            Rect frame = new Rect();
            getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
            statusBarHeight = frame.top;
//            Logg.w("www", "" + statusBarHeight);
        }

        // 获取屏幕长和高
//        int width = getWindowManager().getDefaultDisplay().getWidth();

        // 去掉标题栏
        bitmap = Bitmap.createBitmap(bitmap, (int) (contentView.getWidth() / 3f), statusBarHeight, (int) (contentView.getWidth() * 2f / 3), 80);
        view.destroyDrawingCache();

        final int primaryColor = getResources().getColor(R.color.colorPrimary);

        // 异步加载
        Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
            public void onGenerated(Palette p) {

                int color = p.getDarkVibrantColor(primaryColor);
                if (color != primaryColor) {
                    StatusBarUtils.setWindowStatusBarColor(WebActivity.this, color);
                }
            }
        });

    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {

        switch (keyCode) {
            case KeyEvent.KEYCODE_BACK:
                if (webView.canGoBack()) {
                    webView.goBack();//webView回退
                    return true;
                } else {
                    finish();//退出Activity。重写后，Activity不退出。
                }
                break;
            case KeyEvent.KEYCODE_MENU:
                switchSelectDialog();
                break;
            default:
                break;
        }
        return super.onKeyUp(keyCode, event);
    }


    private ValueCallback<Uri> uploadMessage;
    private ValueCallback<Uri[]> uploadMessageAboveL;
    private final static int FILE_CHOOSER_RESULT_CODE = 10000;


    private void openImageChooserActivity() {
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("image/*");
        startActivityForResult(Intent.createChooser(i, "Image Chooser"), FILE_CHOOSER_RESULT_CODE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == FILE_CHOOSER_RESULT_CODE) {
            if (null == uploadMessage && null == uploadMessageAboveL) {
                return;
            }
            Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
            if (uploadMessageAboveL != null) {
                onActivityResultAboveL(requestCode, resultCode, data);
            } else if (uploadMessage != null) {
                uploadMessage.onReceiveValue(result);
                uploadMessage = null;
            }
        }
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void onActivityResultAboveL(int requestCode, int resultCode, Intent intent) {
        if (requestCode != FILE_CHOOSER_RESULT_CODE || uploadMessageAboveL == null) {
            return;
        }
        Uri[] results = null;
        if (resultCode == Activity.RESULT_OK) {
            if (intent != null) {
                String dataString = intent.getDataString();
                ClipData clipData = intent.getClipData();
                if (clipData != null) {
                    results = new Uri[clipData.getItemCount()];
                    for (int i = 0; i < clipData.getItemCount(); i++) {
                        ClipData.Item item = clipData.getItemAt(i);
                        results[i] = item.getUri();
                    }
                }
                if (dataString != null) {
                    results = new Uri[]{Uri.parse(dataString)};
                }
            }
        }
        uploadMessageAboveL.onReceiveValue(results);
        uploadMessageAboveL = null;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        hideLoading();
        progressDialog = null;
        hideSelectDialog();
        selectDialog = null;

        if (webView != null) {
//            webView.clearHistory();
//            webView.clearCache(true);
//            webView.loadUrl("about:blank"); // clearView() should be changed to loadUrl("about:blank"), since clearView() is deprecated now
//            webView.clearCache(true);
//            webView.pauseTimers();
            webView.destroy();
            webView = null; // Note that mWebView.destroy() and mWebView = null do the exact same thing
        }
        unregisterReceiver(downloadReceiver);

    }

    //广播接收者，接收下载状态
    private class DownloadReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent != null) {
                long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
                if (downloadId != -1) {
                    checkDownloadStatus(downloadId);//检查下载状态
                }
            }
        }

        //检查下载状态
        private void checkDownloadStatus(long downLoadId) {
            DownloadManager.Query query = new DownloadManager.Query();
            DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
            query.setFilterById(downLoadId);//筛选下载任务，传入任务ID，可变参数
            Cursor c = downloadManager.query(query);
            if (c.moveToFirst()) {
                int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
                switch (status) {
                    case DownloadManager.STATUS_PAUSED:
                        Logg.d(">>", "暂停");
                    case DownloadManager.STATUS_PENDING:
                        Logg.d(">>", "延迟");
                    case DownloadManager.STATUS_RUNNING:
                        Logg.d(">>", "进行中");
                        break;
                    case DownloadManager.STATUS_SUCCESSFUL:
                        Toast.makeText(WebActivity.this, "下载成功", Toast.LENGTH_SHORT).show();

                        //获取文件下载路径
                        String absPath = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));

                        String parent = new File(absPath).getParent();

                        Logg.d(">>>", absPath);

                        openToFolder(absPath);

                        Logg.d(">>", "成功");
                        break;
                    case DownloadManager.STATUS_FAILED:

                        Toast.makeText(WebActivity.this, "下载失败", Toast.LENGTH_SHORT).show();

                        Logg.d(">>", "失败");
                        break;
                }
            }
        }

    }

    private String getAppHomeSDCardDir() {
        return Environment.getExternalStorageDirectory().getAbsolutePath() + "/dogbrowser";
    }

    private void openToFolder(String path) {

        File file = new File(path);
        //获取父目录
        File parentFlie = new File(file.getParent());
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setDataAndType(Uri.fromFile(parentFlie), "*/*");
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        startActivity(intent);

    }

    private class ResDownloadListener implements DownloadListener {

        @Override
        public void onDownloadStart(final String url, String userAgent, final String contentDisposition, final String mimeType, final long contentLength) {

            Logg.w(">>>", "申请权限");

            requirePermisson(10001, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, new PermissonCallback() {
                @Override
                public void callBack(boolean hasPer, String[] permissions, int[] grantResults) {

                    double lenM = contentLength / 1024 / 1024;
                    String lenMStr = String.format("%.2f", lenM).toString();
                    String fileName = URLUtil.guessFileName(url, contentDisposition, mimeType);

                    if (hasPer) {

                        fileName = getOnlyFileName(fileName);
                        String path = getAppHomeSDCardDir();

                        final String finalFileName = fileName;
                        Logg.d(">>>onlu", finalFileName);
                        new AlertDialog.Builder(WebActivity.this)
                                .setTitle("下载")
                                .setMessage("文件大小：" + lenMStr + "M，是否下载到此文件夹中？\n" + path)
                                .setPositiveButton("确定", new DialogInterface.OnClickListener() {

                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {

                                        downloadBySystem(url, finalFileName);
                                        dialog.dismiss();
                                    }

                                })
                                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        dialog.dismiss();
                                    }
                                }).show();


                    } else {
                        Toast.makeText(WebActivity.this, "没有Sd卡读写权限，无法下载", Toast.LENGTH_SHORT).show();
                    }
                }
            });

        }


        /**
         * @param fileName
         * @return 如果文件有同名，返回fileName(xx)，xx是符合fileName(xx)文件中最大数字加一。
         */
        private String getOnlyFileName(String fileName) {
            File file = new File(getAppHomeSDCardDir() + "/" + fileName);
            File parent = file.getParentFile();
            parent.mkdirs();//父目录不存在，一般情况下其中的内容是空的。但不是绝对的，可以删除文件夹，但子文件依然存在，只是找不到。
            String[] fileList = parent.list();

            Logg.w(">>>", file.getAbsolutePath() + "||||" + file.getParentFile().canWrite());

            int index = fileName.lastIndexOf('.');

            String startStr = fileName;
            String endStr = "";

            if (index != -1) {
                startStr = fileName.substring(0, index);
                endStr = fileName.substring(index, fileName.length());
            }


            long dTemp = 0;
            String midTemp = "";
            for (int i = 0; i < fileList.length; i++) {

                //文件存在重复
                if (fileList[i].startsWith(startStr)) {
                    String midStr = fileList[i].substring(startStr.length(), fileList[i].length() - endStr.length());
                    if (midStr.matches("\\([\\d]+\\)")) {
                        long d = Long.parseLong(midStr.substring(1, midStr.length() - 1));
                        if (d > dTemp) {
                            dTemp = d;
                            midTemp = midStr;
                        }
                    }
                }
            }

            if (!TextUtils.isEmpty(midTemp)) {
                dTemp++;
                fileName = startStr + '(' + dTemp + ")" + endStr;
            }

            return fileName;

        }

        //系统下载
        private void downloadBySystem(String url, String fileName) {
            // 指定下载地址
            DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
            // 允许媒体扫描，根据下载的文件类型被加入相册、音乐等媒体库
            request.allowScanningByMediaScanner();
            // 设置通知的显示类型，下载进行时和完成后显示通知
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
            // 设置通知栏的标题，如果不设置，默认使用文件名
//        request.setTitle("This is title");
            // 设置通知栏的描述
//        request.setDescription("This is description");
            // 允许在计费流量下下载
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                request.setAllowedOverMetered(false);
            }
            // 允许该记录在下载管理界面可见
            request.setVisibleInDownloadsUi(false);
            // 允许漫游时下载
            request.setAllowedOverRoaming(true);
            // 允许下载的网路类型
            request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);

            File file = new File(getAppHomeSDCardDir() + "/" + fileName);
            request.setDestinationUri(Uri.fromFile(file));

            // 设置下载文件保存的路径和文件名
//        request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);

//        这个的下载目录形如：/storage/emulated/0/Android/data/com.lu.dog.dbrowser/files/dogbrowser/
//        会下载到sd卡的Android目录中
//            request.setDestinationInExternalFilesDir(WebActivity.this, "dogbrowser", fileName);


            final DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
            // 添加一个下载任务
            long downloadId = downloadManager.enqueue(request);
            Logg.d(">>>下载id", downloadId);
        }
    }
}
